#include "Shader.h"
#include <iostream>
#include <string.h>
using namespace std;

Shader::Shader(ShaderBase *vtshader, ShaderBase *pcshader) :
_vtshader(vtshader), _pcshader(pcshader), _created(false)
{
    if(_vtshader && _pcshader)
        create();
}

Shader::~Shader()
{
    if(glIsProgramARB(_program))
      {
	glDetachObjectARB(_program, _vtshader->getGLID());
	glDetachObjectARB(_program, _pcshader->getGLID());
        glDeleteObjectARB(_program);
      }
    if(_vtshader)
        delete _vtshader;
    if(_pcshader)
        delete _pcshader;
}

void Shader::create()
{
    GLint link_status = GL_TRUE;
    GLint logsize = 0;
    char *log = NULL;

    _program = glCreateProgramObjectARB();

    if(_vtshader)
        glAttachObjectARB(_program, _vtshader->getGLID());
    if(_pcshader)
        glAttachObjectARB(_program, _pcshader->getGLID());

    glLinkProgramARB(_program);

    glGetObjectParameterivARB(_program, GL_LINK_STATUS, &link_status);
    if(link_status != GL_TRUE)
    {
        glGetObjectParameterivARB(_program, GL_INFO_LOG_LENGTH, &logsize);
        log = new char[logsize + 1];

        memset(log, '\0', logsize + 1);
        glGetInfoLogARB(_program, logsize, &logsize, log);

        cout << "Couldn't create shader : " << log << "\n";

        delete[] log;
        glDeleteObjectARB(_program);
    }
    else
        _created = true;
}

void Shader::setShader(bool set)
{
    if(_created)
    {
      if(set)
	glUseProgramObjectARB(getProgram());
      else
	glUseProgramObjectARB(0);
    }
}

bool Shader::isShader()
{
    return _created;
}

GLuint Shader::getProgram() const
{
    return _program;
}

ShaderBase *Shader::getVertexShader() const
{
    return _vtshader;
}

ShaderBase *Shader::getPixelShader() const
{
    return _pcshader;
}

